from abc import ABC, abstractmethod
from typing import List, Dict, Any, Optional, Type

class BaseLLM(ABC):
    """LLM基类"""
    
    @staticmethod
    def get_llm(llm_name: str) -> 'BaseLLM':
        """
        通过名称获取对应的LLM实例
        """
        # 标准化名称处理
        normalized_name = llm_name.lower().replace('llm', '')  # 移除 llm 后缀并转小写
        
        for llm_class in BaseLLM.__subclasses__():
            # 对比时也标准化类名
            class_name = llm_class.__name__.lower().replace('llm', '')
            if class_name == normalized_name:
                return llm_class()
            
        # 如果没找到，打印所有可用的LLM类名
        available_llms = [cls.__name__ for cls in BaseLLM.__subclasses__()]
        raise ValueError(f"未找到名为 {llm_name} 的LLM实现类。可用的LLM类型: {available_llms}")
    
    @abstractmethod
    def generate(self, prompt: str) -> str:
        """
        生成回答
        参数:
            prompt: 输入提示
        返回:
            生成的回答文本
        """
        pass
    
    def _build_prompt(
        self,
        question: str,
        context: List[Dict[str, Any]]
    ) -> str:
        """
        构建提示词
        参数:
            question: 用户问题
            context: 相关文档上下文
        返回:
            完整的提示词
        """
        context_str = "\n".join(
            f"文档{i+1}：{doc['content']}"
            for i, doc in enumerate(context)
        )
        
        return f"""请基于以下参考文档回答问题。如果无法从参考文档中得到答案，请说明。

参考文档：
{context_str}

问题：{question}

回答："""
